package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersCancelDTO;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersRejectionDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrdersMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.service.OrdersService;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.vo.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * PROJECT_NAME: sky-take-out
 * NAME: OrdersServiceImpl
 *
 * @AUTHOR: zhang
 * DATE: 2023/12/13
 * DESCRIPTION :
 */
@Service
public class OrdersServiceImpl implements OrdersService {
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private AddressBookMapper addressBookMapper;
    @Resource
    private ShoppingCartMapper shoppingCartMapper;
    @Resource
    private OrderDetailMapper orderDetailMapper;

    /**
     * 提交订单
     *
     * @param ordersSubmitDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        //1.添加订单基本信息
        //根据地址id查询地址信息
        Long addressBookId = ordersSubmitDTO.getAddressBookId();
        AddressBook addressBook = addressBookMapper.selectAddressBookById(addressBookId);
        //校验
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }


        //属性拷贝
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        //补齐字段
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setStatus(1);
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setPayStatus(0);
        //收货人手机号
        orders.setPhone(addressBook.getPhone());
        //收货人详细地址
        orders.setAddress(addressBook.getDetail());
        //用户姓名
        //收货人
        orders.setConsignee(addressBook.getConsignee());
        //取消原因
        //拒绝原因
        //取消时间
        orders.setCancelTime(LocalDateTime.now());
        //实际送达时间
        orders.setDeliveryTime(LocalDateTime.now());

        //入库
        ordersMapper.insert(orders);

        //2.保存订单详情
        //获取当前用户id
        Long userId = BaseContext.getCurrentId();
        //根据当前用户查询购物车中的商品
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.selectShoppingCart(shoppingCart);
        //检验
        if (shoppingCartList == null) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //遍历添加
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            //补齐字段 订单id 更新时间 修改时间
            orderDetail.setOrderId(orders.getId());
            orderDetail.setCreateTime(LocalDateTime.now());
            orderDetail.setUpdateTime(LocalDateTime.now());
            //todo:添加
            orderDetailMapper.insert(orderDetail);
        }

        //3.下单完成清空购物车

        shoppingCartMapper.delete(shoppingCart);

        //返回VO
        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setId(orders.getId());
        orderSubmitVO.setOrderAmount(orders.getAmount());
        orderSubmitVO.setOrderNumber(orders.getNumber());
        orderSubmitVO.setOrderTime(LocalDateTime.now());

        return orderSubmitVO;
    }


    /**
     * 查询历史订单
     *
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult getHistoryOrders(OrdersPageQueryDTO ordersPageQueryDTO) {
        //分页
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        //1.查询订单基本信息
        Long userId = BaseContext.getCurrentId();
        //todo:分页查询
        ordersPageQueryDTO.setUserId(userId);
        Page<Orders> ordersList = ordersMapper.selectOrdersByUserId(ordersPageQueryDTO);
        if (ordersList == null || ordersList.size() == 0) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //用于封装返回信息
        List<OrderVO> orderVOList = new ArrayList<>();
        //遍历获取订单信息
        for (Orders orders : ordersList) {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders, orderVO);
            //2.查询订单详情
            Long ordersId = orders.getId();
            List<OrderDetail> orderDetailList = orderDetailMapper.selectOrdersByOrderId(ordersId);
            orderVO.setOrderDetailList(orderDetailList);
            orderVOList.add(orderVO);
        }

        return PageResult.builder().total(ordersList.getTotal()).records(orderVOList).build();
    }

    /**
     * 查询订单详情
     *
     * @param id 订单id
     * @return 订单基本信息+订单详细信息
     */
    @Override
    public OrderVO getOrderDetails(Long id) {
        //用于封装返回信息
        OrderVO orderVO = new OrderVO();
        //根据订单id查询订单基本信息
        Orders orders = ordersMapper.selectOrdersById(id);
        BeanUtils.copyProperties(orders, orderVO);
        //根据订单id查询订单详情
        List<OrderDetail> orderDetailList = orderDetailMapper.selectOrdersByOrderId(id);
        if (orderDetailList == null || orderDetailList.size() == 0) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        orderVO.setOrderDetailList(orderDetailList);
        //封装vo返回
        return orderVO;
    }

    /**
     * 再来一单
     *
     * @param id
     */
    @Override
    public void getOrderAgain(Long id) {
        //根据订单id查询订单详情
        List<OrderDetail> orderDetailList = orderDetailMapper.selectOrdersByOrderId(id);
        //将订单详情转换为购物车信息，并添加到数据库中
        List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(new Function<OrderDetail, ShoppingCart>() {
            @Override
            public ShoppingCart apply(OrderDetail orderDetail) {
                ShoppingCart shoppingCart = new ShoppingCart();
                BeanUtils.copyProperties(orderDetail, shoppingCart);
                shoppingCart.setCreateTime(LocalDateTime.now());
                shoppingCart.setUserId(BaseContext.getCurrentId());
                return shoppingCart;
            }
        }).collect(Collectors.toList());
        //遍历添加
        for (ShoppingCart shoppingCart : shoppingCartList) {
            shoppingCartMapper.insertShoppingCart(shoppingCart);
        }

    }


    /**
     * 订单搜索
     *
     * @param pageQueryDTO
     * @return {@link OrderVO}
     */
    @Override
    public PageResult ordersSearch(OrdersPageQueryDTO pageQueryDTO) {
        //分页
        PageHelper.startPage(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());
        //条件查询
        Page<Orders> ordersPage = ordersMapper.selectOrdersByUserId(pageQueryDTO);
        //保存菜品的信息
        StringBuilder stringBuilder = new StringBuilder();
        //遍历转换为VO
        List<Orders> result = ordersPage.getResult();
        List<OrderVO> orderVOList = new ArrayList<>();
        for (Orders orders : result) {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders, orderVO);
            Long ordersId = orders.getId();
            //根据订单id查询订单详情
            List<OrderDetail> orderDetailList = orderDetailMapper.selectOrdersByOrderId(ordersId);
            for (OrderDetail orderDetail : orderDetailList) {
                String name = orderDetail.getName();
                Integer number = orderDetail.getNumber();
                stringBuilder.append(name).append("*").append(number);
                orderVO.setOrderDishes(stringBuilder.toString());
            }
            orderVOList.add(orderVO);
        }
        //查询订单菜品

        return PageResult.builder().total(ordersPage.getTotal()).records(orderVOList).build();
    }

    /**
     * 各个状态的订单数量统计
     *
     * @return
     */
    @Override
    public OrderStatisticsVO getOrdersStatusNum() {
        //待接单数量
        Integer toBeConfirmed = ordersMapper.getOrdersStatusNum(Orders.TO_BE_CONFIRMED);
        //待派送数量
        Integer confirmed = ordersMapper.getOrdersStatusNum(Orders.CONFIRMED);
        //派送中数量
        Integer delivery = ordersMapper.getOrdersStatusNum(Orders.DELIVERY_IN_PROGRESS);
        return OrderStatisticsVO.builder()
                .toBeConfirmed(toBeConfirmed)
                .confirmed(confirmed)
                .deliveryInProgress(delivery)
                .build();
    }


    /**
     * 查看订单详情
     *
     * @param id 订单id
     * @return {@link OrderVO}
     */
    @Override
    public OrderVO selectOrderDetails(Long id) {
        //创建OrderVO用于数据返回
        OrderVO orderVO = new OrderVO();
        //根据订单id查询订单基本信息
        Orders orders = ordersMapper.selectOrdersById(id);
        BeanUtils.copyProperties(orders, orderVO);
        //根据订单id查询订单详情
        List<OrderDetail> orderDetailList = orderDetailMapper.selectOrdersByOrderId(id);
        //数据返回
        orderVO.setOrderDetailList(orderDetailList);
        return orderVO;
    }

    /**
     * 接单
     *
     * @param orders
     */
    @Override
    public void confirmOrder(Orders orders) {
        //根据订单id查询订单的状态
        orders = ordersMapper.selectOrdersById(orders.getId());
        //如果订单状态不是待接单则提示状态错误
        if (orders==null||!orders.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        //根据订单id修改订单状态
        orders.setStatus(Orders.CONFIRMED);
        ordersMapper.updateOrders(orders);
    }

    /**
     * 拒绝订单
     * @param ordersRejectionDTO
     */
    @Override
    public void cancelOrder(OrdersRejectionDTO ordersRejectionDTO) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersRejectionDTO,orders);
        //取消时间
        orders.setCancelTime(LocalDateTime.now());
        //状态已取消
        orders.setStatus(Orders.CANCELLED);
        //已退款
        orders.setPayStatus(Orders.REFUND);
        //修改
        ordersMapper.updateOrders(orders);
    }

    /**
     * 取消订单
     * @param ordersCancelDTO
     */
    @Override
    public void cancelOrders(OrdersCancelDTO ordersCancelDTO) {
        Orders orders = ordersMapper.selectOrdersById(ordersCancelDTO.getId());
        if (orders == null||orders.getStatus()<Orders.CONFIRMED&&orders.getStatus()>Orders.COMPLETED) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        //修改订单信息
        BeanUtils.copyProperties(ordersCancelDTO,orders);
        //取消原因
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());
        orders.setPayStatus(Orders.REFUND);
        //更新
        ordersMapper.updateOrders(orders);
    }

    /**
     * 派送订单
     * @param id 订单id
     */
    @Override
    public void deliveryOrders(Long id) {
        //检验
        Orders orders = ordersMapper.selectOrdersById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //更新状态
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        ordersMapper.updateOrders(orders);
    }

    /**
     * 完成订单
     * @param id 订单id
     */
    @Override
    public void completeOrder(Long id) {
        //检验
        Orders orders = ordersMapper.selectOrdersById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //更新状态为已完成
        orders.setStatus(Orders.COMPLETED);
        //送达时间
        orders.setDeliveryTime(LocalDateTime.now());
        //更新
        ordersMapper.updateOrders(orders);
    }
}
